#include "mempool.h"


// 创建内存池
MemoryPool* createPool(size_t blockSize, size_t blockCount) 
{
    MemoryPool* pool = (MemoryPool*)malloc(sizeof(MemoryPool));
    if (!pool) return NULL;

    size_t actualBlockSize = blockSize + sizeof(void*);// 每个块需至少容纳一个指针（用于链表）

    pool->blockSize = blockSize;
    pool->blockCount = blockCount;
    pool->data = (char*)malloc(actualBlockSize * blockCount);
    if (!pool->data) 
    {
        free(pool);
        return NULL;
    }

    // 初始化空闲链表：将所有块串联起来
    pool->freeList = pool->data;
    for (size_t i = 0; i < blockCount - 1; ++i) 
    {
        void* current = pool->data + i * actualBlockSize;
        void* next = pool->data + (i + 1) * actualBlockSize;
        *(void**)current = next;//把next的地址放到current所指的内存中去
        // 注意甄别(这里是难点也是重点)：
        // current指向next的内存地址，current原来的内存变成野指针
        // current = next;
    }
    // 最后一个块的next置为NULL
    void* last = pool->data + (blockCount - 1) * actualBlockSize;
    *(void**)last = NULL;

    return pool;
}

// 销毁内存池
int destroyPool(MemoryPool* pool) 
{
    if (pool == NULL)
    {
        return -1;
    }
    else
    {
        free(pool->data);
        free(pool);
        return 0;
    }
}

// 从内存池分配一块内存
void* allocate(MemoryPool* pool) 
{
    if (!pool || !pool->freeList) return NULL;

    void* result = pool->freeList; 
    pool->freeList = *(void**)result;// 移动链表头到下一个空闲块
    return (char*)result + sizeof(void*);// 返回用户可用的内存区域（跳过链表指针部分）
}

// 将内存块释放回内存池
int deallocate(MemoryPool* pool, void* ptr) 
{
    if (!pool || !ptr) return -1;

    // 计算原始块地址（包含链表指针的位置）
    void* block = (char*)ptr - sizeof(void*);
    // 将块插入空闲链表头部
    *(void**)block = pool->freeList;
    pool->freeList = block;
}